package oo.shootgame;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;//I指input,O指output imageIO指图片的输入输出
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.util.Arrays;
import java.util.Timer;
import java.util.TimerTask;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.Color;
import java.awt.Font;

public class ShootGame extends JPanel{
	/**设定窗口大小*/
	public static final int WIDTH=500;
	public static final int HEIGHT=1024;
	/**状态*/
	public static final int START=0;
	public static final int RUNNING=1;
	public static final int PAUSE=2;
	public static final int GAME_OVER=3;
	public static final int KILL_BOSS=4;
	private static int state=0;
	/**定义图片*/
	public static BufferedImage background;
	public static BufferedImage gameover;
	public static BufferedImage start;
	public static BufferedImage pause;
	public static BufferedImage airplane;
	public static BufferedImage bee;
	public static BufferedImage bullet;
	public static BufferedImage hero0;
	public static BufferedImage hero1;	
	public static BufferedImage bigplane0;
	public static BufferedImage bigplane1;
	public static BufferedImage Boss0;
	public static BufferedImage Boss1;
	public static BufferedImage bossbullet;
	public static BufferedImage bigbullet;
	public static BufferedImage beebullet;
	public static BufferedImage boom0;
	public static BufferedImage boom1;
	public static BufferedImage boom2;
	public static BufferedImage boom3;
	public static BufferedImage boom4;
	public static BufferedImage boom5;	
	public static BufferedImage firstboss0;
	public static BufferedImage firstboss1;
	public static BufferedImage firstboss2;
	public static BufferedImage firstboss3;
	public static BufferedImage firstboss4;
	public static BufferedImage fbossbullet;
	static{ //加载图片资源
		try{
			background=ImageIO.read(ShootGame.class.getResource("background.png"));
			gameover=ImageIO.read(ShootGame.class.getResource("gameover.png"));
			start=ImageIO.read(ShootGame.class.getResource("start.png"));
			pause=ImageIO.read(ShootGame.class.getResource("pause.png"));
			airplane=ImageIO.read(ShootGame.class.getResource("airplane.png"));
			bee=ImageIO.read(ShootGame.class.getResource("bee.png"));
			bullet=ImageIO.read(ShootGame.class.getResource("bullet.png"));
			hero0=ImageIO.read(ShootGame.class.getResource("hero0.png"));
			hero1=ImageIO.read(ShootGame.class.getResource("hero1.png"));
			bigplane0=ImageIO.read(ShootGame.class.getResource("bigplane0.png"));
			bigplane1=ImageIO.read(ShootGame.class.getResource("bigplane1.png"));
			Boss0=ImageIO.read(ShootGame.class.getResource("Boss0.png"));
			Boss1=ImageIO.read(ShootGame.class.getResource("Boss1.png"));
			bossbullet=ImageIO.read(ShootGame.class.getResource("bossbullet.png"));
			bigbullet=ImageIO.read(ShootGame.class.getResource("bigbullet.png"));
			beebullet=ImageIO.read(ShootGame.class.getResource("beebullet.png"));
			boom0=ImageIO.read(ShootGame.class.getResource("boom0.png"));
			boom1=ImageIO.read(ShootGame.class.getResource("boom1.png"));
			boom2=ImageIO.read(ShootGame.class.getResource("boom2.png"));
			boom3=ImageIO.read(ShootGame.class.getResource("boom3.png"));
			boom4=ImageIO.read(ShootGame.class.getResource("boom4.png"));
			boom5=ImageIO.read(ShootGame.class.getResource("boom5.png"));
			firstboss0=ImageIO.read(ShootGame.class.getResource("firstboss0.png"));
			firstboss1=ImageIO.read(ShootGame.class.getResource("firstboss1.png"));
			firstboss2=ImageIO.read(ShootGame.class.getResource("firstboss2.png"));
			firstboss3=ImageIO.read(ShootGame.class.getResource("firstboss3.png"));
			firstboss4=ImageIO.read(ShootGame.class.getResource("firstboss4.png"));
			fbossbullet=ImageIO.read(ShootGame.class.getResource("fbossbullet.png"));
		}catch(Exception e){//抓异常
			e.printStackTrace();//打印出堆栈消息
		}
	}
	/**画板*/
	public void paint(Graphics g){
		g.drawImage(background, 0, 0, null);
		this.painthero(g);
		paintflys(g);
		paintbullets(g);
		paintboom(g);
		paintScore(g);
		paintState(g);
		paintLevel(g);
		
	}
	public void paintState(Graphics g){
		switch(state){
			case START:
				g.drawImage(start,0,0,null);
				break;
			case PAUSE:
				g.drawImage(pause,0,0,null);
				break;
			case GAME_OVER:
				g.drawImage(gameover,0,0,null);
				break;
		}
	}
	public void paintScore(Graphics g){
		Color c=new Color(0xff0000);
		Font font=new Font(Font.SANS_SERIF,Font.BOLD,20);
		g.setColor(c);
		g.setFont(font);
		g.drawString("Score:"+score,10,25);
		g.drawString("Life:"+hero.life,10,45);
		g.drawString("Doublefire:"+hero.doublefire,10,65);
		g.drawString("Boom:"+hero.boom,10,85);
	}
	int paintbo=0;
	public void paintLevel(Graphics g){
		Color c=new Color(0xff0000);
		Font font=new Font(Font.SANS_SERIF,Font.BOLD,35);
		g.setColor(c);
		g.setFont(font);
		for(int i=1;i<5;i++){
			if(enter==100*60*i && paintbo<200){
				paintbo++;
				g.drawString("the BOSS of "+i,150,350);
			}
		}
	}
	
	private Hero hero=new Hero();
	public void painthero(Graphics g){
		g.drawImage(hero.image,hero.x,hero.y,null);
	}
	
	
	private Boom[] boom={};
	/**
	 * 画炸弹
	 */
	public void paintboom(Graphics g){
		for(int i=0;i<boom.length;i++){
			g.drawImage(boom[i].image,boom[i].x,boom[i].y,null);
		}
	}
	
	private Bullet[] bullets={};
	private Bullet[] beebullets={};
	private Bullet[] bigbullets={};
	private Bullet[] bossbullets={};
	private Bullet[] fbossbullets={};
	public void paintbullets(Graphics g){
		for(int i=0;i<bullets.length;i++){
			g.drawImage(bullets[i].image, bullets[i].x,bullets[i].y,null);
		}
		for(int j=0;j<beebullets.length;j++){
			g.drawImage(beebullet, beebullets[j].x,beebullets[j].y,null);
		}
		for(int k=0;k<bigbullets.length;k++){
			g.drawImage(bigbullet, bigbullets[k].x,bigbullets[k].y,null);
		}
		for(int p=0;p<bossbullets.length;p++){
			g.drawImage(bossbullet, bossbullets[p].x,bossbullets[p].y,null);
		}
		for(int q=0;q<fbossbullets.length;q++){
			g.drawImage(fbossbullet, fbossbullets[q].x,fbossbullets[q].y,null);
		}		
	}
	
	private Plane[] flys={};
	public void paintflys(Graphics g){
		for(int i=0;i<flys.length;i++){
			g.drawImage(flys[i].image, flys[i].x,flys[i].y,null);
		}
	}
	/**画板*/

	private Timer timer=new Timer();
	private int interval=10;
	public void action(){
		/**侦听器*/
		MouseAdapter ll=new MouseAdapter(){
			public void mouseMoved(MouseEvent e){
				if(state==RUNNING||state==KILL_BOSS){
					int x=e.getX();
					int y=e.getY();
					hero.moveto(x,y);
				}
			}
			public void mouseClicked(MouseEvent e){
				switch(state){
					case START:
						state=RUNNING;
						break;
					case GAME_OVER:
						hero.life=50;
						score=0;
						flys=new Plane[0];
						bullets=new Bullet[0];
						beebullets=new Bullet[0];
						bigbullets=new Bullet[0];
						bossbullets=new Bullet[0];
						state=START;
						break;
					case RUNNING:
					case KILL_BOSS:
						if(hero.boom>0){
							hero.boom--;
							Boom booms=hero.boom();
							boom=Arrays.copyOf(boom,boom.length+1);
							boom[boom.length-1]=booms;
						}
						break;
				}
			}
			public void mouseExited(MouseEvent e){
				if(state==RUNNING||state==KILL_BOSS){
					state=PAUSE;
				}
			}
			public void mouseEntered(MouseEvent e){
				if(state==PAUSE){					
					if(enter==100*60||enter==100*60*2||enter==100*60*3||enter==100*60*4){
						state=KILL_BOSS;
					}else{
						state=RUNNING;
					}
				}
			}
		};
		this.addMouseMotionListener(ll);
		this.addMouseListener(ll);
		/**定时器*/
		timer.schedule(new TimerTask(){
			public void run(){
				if(state==KILL_BOSS){
					stepAction();
					shootAction();
					outbroundAction();
					bangAcTion();
					hitAction();
					boomAction();
					IsGameOverAction();
				}
				if(state==RUNNING){
					enterAction();
					stepAction();
					shootAction();
					outbroundAction();
					bangAcTion();
					hitAction();
					boomAction();
					IsGameOverAction();
					IsBossAction();
				}
				repaint();
			}
		}, interval,interval);
	}
	
	public static Plane nextOne(){
		for(int i=1;i<5;i++){
			if(enter==100*60*i){
				state=KILL_BOSS;
				return new FirstBoss();
			}
		}
		if((score+5)%500==0){
			score+=5;
			return new Boss();			
		}
		int span=(int)(Math.random()*20);
		if(span<1){
			return new BigPlane();
		}else if(span<6){
			return new Bee();
		}else{
			return new AirPlane();
		}		
	}
	private static int enter=0;
	public void enterAction(){
		enter++;
		int speeds;
		if(enter<100*60){
			speeds=30;
		}else if(enter<100*120){
			speeds=20;
		}else if(enter<100*180){
			speeds=15;
		}else{
			speeds=10;
		}
		if(enter%speeds==0){
			Plane fly=nextOne();
			flys=Arrays.copyOf(flys,flys.length+1);
			flys[flys.length-1]=fly;
		}
	}
	public void boomAction(){
		for(int i=0;i<boom.length;i++){
			if(boom[i].image==boom[i].images[boom[i].images.length-1]){
				for(int j=0;j<flys.length;j++){
					if(flys[j] instanceof FirstBoss){
						flys[j].life=flys[j].life-100;
					}else{
						flys[j]=flys[flys.length-1];
						flys=Arrays.copyOf(flys, flys.length-1);
					}
				}
				beebullets=new Bullet[0];
				bigbullets=new Bullet[0];
				bossbullets=new Bullet[0];
				fbossbullets=new Bullet[0];
				boom=new Boom[0];				
				break;
			}
		}
	}
	public void stepAction(){
		for(int i=0;i<flys.length;i++){
			flys[i].step();
		}
		for(int j=0;j<bullets.length;j++){
			if(hero.doublefire>0){
				bullets[j].step();
				if(j%3==0){
					bullets[j].xstep1();
				}
				if(j%3==2){
					bullets[j].xstep2();
				}
			}else{
				bullets[j].step();
			}
		}
		for(int k=0;k<beebullets.length;k++){
			beebullets[k].beestep();
		}
		for(int p=0;p<bigbullets.length;p++){
			bigbullets[p].bigbstep();
		}
		for(int q=0;q<bossbullets.length;q++){
			bossbullets[q].bigbstep();
			if(q%3==0){
				bossbullets[q].xstep1();
			}
			if(q%3==2){
				bossbullets[q].xstep2();
			}			
		}
		for(int r=0;r<boom.length;r++){
			boom[r].step();
		}	
		for(int t=0;t<fbossbullets.length;t++){
			fbossbullets[t].bigbstep();
			if(t%5==0||t%5==1){
				fbossbullets[t].xstep1();
			}			
			if(t%5==3||t%5==4){
				fbossbullets[t].xstep2();
			}
		}	
		hero.step();
	}
	private int shoot=0;
	public void shootAction(){
		shoot++;
		if(shoot%15==0){
			Bullet[] bb=hero.shoot();
			bullets=Arrays.copyOf(bullets,bullets.length+bb.length);
			System.arraycopy(bb, 0, bullets, bullets.length-bb.length, bb.length);
		}
		if(shoot%100==0){
			for(int i=0;i<flys.length;i++){
				if(flys[i] instanceof Bee){
					Bee fly=(Bee)flys[i];
					Bullet bee=fly.beeshoot();
					beebullets=Arrays.copyOf(beebullets,beebullets.length+1);
					beebullets[beebullets.length-1]=bee;
				}
				if(flys[i] instanceof BigPlane){
					BigPlane big=(BigPlane)flys[i];
					Bullet[] bigb=big.bigshoot();
					bigbullets=Arrays.copyOf(bigbullets,bigbullets.length+bigb.length);
					System.arraycopy(bigb, 0, bigbullets, bigbullets.length-bigb.length, bigb.length);
				}
				if(flys[i] instanceof Boss){
					Boss bos=(Boss)flys[i];
					Bullet[] bosb=bos.BossShoot();
					bossbullets=Arrays.copyOf(bossbullets,bossbullets.length+bosb.length);
					System.arraycopy(bosb, 0, bossbullets,bossbullets.length-bosb.length, bosb.length);
				}	
				if(flys[i] instanceof FirstBoss){
					FirstBoss fboss=(FirstBoss)flys[i];
					Bullet[] fb={};
					if(fboss.life>200){
						if(shoot/100%fboss.images.length==0){
							fb=fboss.shoot1();						
						}
						if(shoot/100%fboss.images.length==1){
							fb=fboss.shoot2();
						}
						if(shoot/100%fboss.images.length==2){
							fb=fboss.shoot3();
						}
						if(shoot/100%fboss.images.length==3){
							fb=fboss.shoot4();
						}
						if(shoot/100%fboss.images.length==4){
							fb=fboss.shoot5();
						}
					}else{
						fb=fboss.shoot6();
					}
					fbossbullets=Arrays.copyOf(fbossbullets,fbossbullets.length+fb.length);
					System.arraycopy(fb, 0, fbossbullets, fbossbullets.length-fb.length, fb.length);
				}
			}
		}
	}
	public void outbroundAction(){
		int outff=0;
		Plane[] fly=new Plane[flys.length];
		for(int i=0;i<flys.length;i++){
			if(flys[i].y<=HEIGHT){				
				fly[outff]=flys[i];
				outff++;
			}
		}
		flys=Arrays.copyOf(fly, outff);
		
		int outbb=0;
		Bullet[] bb=new Bullet[bullets.length];
		for(int j=0;j<bullets.length;j++){
			if(bullets[j].y>=-bullets[j].height){				
				bb[outbb]=bullets[j];
				outbb++;
			}
		}
		bullets=Arrays.copyOf(bb, outbb);
		
		int outbigb=0;
		Bullet[] bbig=new Bullet[bigbullets.length];
		for(int k=0;k<bigbullets.length;k++){
			if(bigbullets[k].y<=HEIGHT){				
				bbig[outbigb]=bigbullets[k];
				outbigb++;
			}
		}
		bigbullets=Arrays.copyOf(bbig, outbigb);
		
		int outbeeb=0;
		Bullet[] bbee=new Bullet[beebullets.length];
		for(int p=0;p<beebullets.length;p++){
			if(beebullets[p].y<=HEIGHT){				
				bbee[outbeeb]=beebullets[p];
				outbeeb++;
			}
		}
		beebullets=Arrays.copyOf(bbee, outbeeb);
		
		int outbosb=0;
		Bullet[] bbos=new Bullet[bossbullets.length];
		for(int q=0;q<bossbullets.length;q++){
			if(bossbullets[q].y<=HEIGHT){				
				bbos[outbosb]=bossbullets[q];
				outbosb++;
			}
		}
		bossbullets=Arrays.copyOf(bbos, outbosb);
		
		int outfbosb=0;
		Bullet[] fbbos=new Bullet[fbossbullets.length];
		for(int r=0;r<fbossbullets.length;r++){
			if(fbossbullets[r].y<=HEIGHT){				
				fbbos[outfbosb]=fbossbullets[r];
				outfbosb++;
			}
		}
		fbossbullets=Arrays.copyOf(fbbos, outfbosb);
	}
	
	public static int score=0;
	public void bangAcTion(){
		boolean[] flagff=new boolean[flys.length];
		boolean[] flagbb=new boolean[bullets.length];
		for(int i=0;i<bullets.length;i++){			
			for(int j=0;j<flys.length;j++){
				if(flys[j].shootby(bullets[i])){
					flagff[j]=true;
					flagbb[i]=true;
					break;
				}
			}			
		}
		for(int k=0;k<flys.length;k++){
		    if(flagff[k]){
		    	if(flys[k] instanceof FirstBoss){
		    		FirstBoss fboss=(FirstBoss)flys[k];
		    		fboss.image=fboss.images[4];
		    		fboss.life--;
		    	}
		    	if(flys[k] instanceof Boss){
		    		Boss bos=(Boss)flys[k];
		    		bos.image=Boss1;
		    		bos.lifedown();		    		
		    	}	
		    	if(flys[k] instanceof BigPlane){//引用相等,指针指向同一个对象
		    		BigPlane big=(BigPlane)flys[k];
		    		big.lifedown();		    		
		    	}		    	
                if(flys[k].life==0){
                	if(flys[k] instanceof FirstBoss){
                		enter++;
                		state=RUNNING;
                	}
                	if(flys[k] instanceof Emeny){
    		    		Emeny e=(Emeny)flys[k];
    		    		score+=e.getScore();
    		    	}
                    if(flys[k] instanceof Award){
                    	Award a=(Award)flys[k];
                    	int b=a.getType();
    		    		switch(b){
	    		    		case Award.DOUBLE_FIRE:
	    		    			hero.addDoubleFire();
	    		    			break;
	    		    		case Award.LIFE:
	    		    			hero.addlife();
	    		    			break;
	    		    		case Award.BOOM:
	    		    			hero.boom++;
    		    		}
    		    	}
			    	flys[k]=flys[flys.length-1];
			    	flys=Arrays.copyOf(flys,flys.length-1);
                }                
		    }
		}
		for(int p=0;p<bullets.length;p++){
			if(flagbb[p]){
				bullets[p]=bullets[bullets.length-1];
		    	bullets=Arrays.copyOf(bullets,bullets.length-1);
			}
		}	
	}
	
	public void hitAction(){
		for(int i=0;i<flys.length;i++){
			if(hero.hitby(flys[i])){
				if(flys[i] instanceof Boss){	
					hero.setDoublefire();
					hero.lifedown();
					hero.y+=75;
				}else if(flys[i] instanceof FirstBoss){
					hero.setDoublefire();
					hero.lifedown();
					hero.y+=100;
				}else{
					hero.setDoublefire();
					hero.lifedown();
					flys[i]=flys[flys.length-1];
					flys=Arrays.copyOf(flys,flys.length-1);
				}
			}
		}
		for(int j=0;j<beebullets.length;j++){
			if(hero.hitby(beebullets[j])){
				hero.setDoublefire();
				hero.lifedown();
				beebullets[j]=beebullets[beebullets.length-1];
				beebullets=Arrays.copyOf(beebullets,beebullets.length-1);
			}
		}
		for(int k=0;k<bigbullets.length;k++){
			if(hero.hitby(bigbullets[k])){
				hero.setDoublefire();
				hero.lifedown();
				bigbullets[k]=bigbullets[bigbullets.length-1];
				bigbullets=Arrays.copyOf(bigbullets,bigbullets.length-1);
			}
		}
		for(int p=0;p<bossbullets.length;p++){
			if(hero.hitby(bossbullets[p])){
				hero.setDoublefire();
				hero.lifedown();
				bossbullets[p]=bossbullets[bossbullets.length-1];
				bossbullets=Arrays.copyOf(bossbullets,bossbullets.length-1);
			}
		}
		for(int q=0;q<fbossbullets.length;q++){
			if(hero.hitby(fbossbullets[q])){
				hero.setDoublefire();
				hero.lifedown();
				fbossbullets[q]=fbossbullets[fbossbullets.length-1];
				fbossbullets=Arrays.copyOf(fbossbullets,fbossbullets.length-1);
			}
		}
	}
	public void IsGameOverAction(){
		if(enter>100*60*4){
			state=GAME_OVER;;
		}
		if(hero.life<=0){
			state=GAME_OVER;
		}
	}
	public void IsBossAction(){
		for(int i=1;i<5;i++){
			if(enter==100*60*i){
				state=KILL_BOSS;
			}
		}
	}
	
	public static void main(String[] args) {
		JFrame frame=new JFrame("Fly");
		ShootGame game=new ShootGame();
		frame.add(game);
		frame.setSize(WIDTH,HEIGHT);
		frame.setAlwaysOnTop(true);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
		game.action();
		

}
}
